package com.caishi.lkx.user.model;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.caishi.lkx.user.ienum.status.UserStatus;
import com.caishi.lkx.user.ienum.type.Sex;
import com.zzw.common.entity.IBaseEntity;
import com.zzw.common.entity.impl.BaseEntity;
import com.zzw.common.service.model.NameModel;
import com.caishi.lkx.user.ienum.type.HaveType;
import com.caishi.lkx.user.ienum.type.UserType;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@EqualsAndHashCode(callSuper = true)
@Data
public abstract class IUserModel<T extends IUserModel<T>> extends BaseEntity<T> implements IBaseEntity<T, String>, NameModel<T, String>/*, IOrderMaster<T, Strin>*/ {

    private Integer userType;

    private String name;

    //@TableField(typeHandler = DataEncryptionHandler.class)
    private String mobile;

    private String header;

    private Sex sex;

    private String apiRoleName;

    private UserStatus userStatus;
    /**
     * 所属平台类型
     */
    private Integer haveType;

    @TableField(typeHandler = FastjsonTypeHandler.class)
    private List<String> otherRoles;

    public UserModel toUserModel() {
        UserModel userModel = new UserModel();
        BeanUtil.copyProperties(this, userModel);
        return userModel;
    }

    /**
     * mybatis plus的缺陷 带上父类的字段会导致insert时将父类字段进行insert 异常
     *
     * @return
     */
    public T clearUserModelMessage() {
        T model = InstanceThisObj();
        BeanUtil.copyProperties(this, model,
                "userType", "name", "sex", "mobile", "header",
                "userStatus", "platformCode", "apiRoleName","haveType","otherRoles");
        return model;
    }


    public T userInfoCopy(UserModel userModel) {
        BeanUtil.copyProperties(userModel, this);
        return (T) this;
    }

    public T clearSensitiveData() {
        this.setMobile(null);
        return (T) this;
    }

    public abstract T InstanceThisObj();


    public UserType[] getUserTypes() {
        if (this.getUserType() == null) {
            return new UserType[]{};
        }
        return UserType.int2Array(this.getUserType());
    }

    public void addUserType(UserType userType) {
        if (userType == null) {
            return;
        }
        if (this.userType == null) {
            this.userType = 0;
        }
        this.userType |= userType.getValue();
    }

    public void addUserType(int val) {
        if (this.userType == null) {
            this.userType = 0;
        }
        this.userType |= val;
    }

    public void delUserType(UserType userType) {
        if (userType == null || this.userType == null) return;
        this.userType &= ~userType.getValue();
    }

    public boolean userTypeOne() {
        if (userType == 0) return true;
        return (int) (Math.log(userType) / Math.log(2)) == Math.log(userType) / Math.log(2);
    }
    public HaveType[] getHaveTypes() {
        if (this.getHaveType() == null) {
            return new HaveType[]{};
        }
        return HaveType.int2Array(this.getHaveType());
    }

    public void addHaveType(HaveType haveType) {
        if (haveType == null) {
            return;
        }
        if (this.haveType == null) {
            this.haveType = 0;
        }
        this.haveType |= haveType.getValue();
    }

    public void addHaveType(int val) {
        if (this.haveType == null) {
            this.haveType = 0;
        }
        this.haveType |= val;
    }

    public void delHaveType(HaveType haveType) {
        if (haveType == null || this.haveType == null) return;
        this.haveType &= ~haveType.getValue();
    }

    public boolean haveTypeOne() {
        if (haveType == 0) return true;
        return (int) (Math.log(haveType) / Math.log(2)) == Math.log(haveType) / Math.log(2);
    }

    public void addApiRoleName(String apiRoleName) {
        if (StrUtil.isNotBlank(apiRoleName)) {
            if (StrUtil.isBlank(this.apiRoleName)) {
                this.apiRoleName = apiRoleName;
                return;
            }
            if (this.apiRoleName.contains(apiRoleName)) {
                return;
            }
            this.apiRoleName += ("," + apiRoleName);
        }
    }

    public void delApiRoleName(String apiRoleName) {
        if (StrUtil.isNotBlank(apiRoleName)) {
            if (StrUtil.isBlank(this.apiRoleName)) {
                return;
            }
            if (!this.apiRoleName.contains(apiRoleName)) {
                return;
            }
            this.apiRoleName = Arrays.stream(this.apiRoleName.split(",")).filter(v -> !v.equals(apiRoleName)).collect(Collectors.joining(","));
        }
    }


}
